<?php
namespace base;

use think\Model;
use think\helper\Str;

class BaseModel extends Model
{
    protected $autoWriteTimestamp = 'datetime';

    /**
     * 插入前置动作,用于数据处理和过滤
     *
     * @var array
     */
    protected $beforeInsertAction = [];

    /**
     * 全局数据权限动作列表，用于权限条件拼接和过滤
     *
     * @var array
     */
    protected $dateRightAction = [];

    /**
     * 自动处理相关权限字段
     * 
     * ['shop'=>['fieldName'=>'shop_id','alias'=>'g_shop_id']]
     *
     * @var array
     */
    protected $rightField = [];

    protected $globalScope = ['dataRight'];

    /**
     * 插入前处理数据
     *
     * @param object $model
     * @return void
     */
    public static function onBeforeInsert($model)
    {
        $eventList = $model->beforeInsertAction??[];

        if(!empty($model->rightField)){
            $model->autoInsertDeal($model);
        }

        if(!empty($eventList)){
            foreach ($eventList as $event) {
                $eventClass = 'app\\task\\data_process\\insert\\'.Str::studly($event);
                if(class_exists($eventClass)){
                    $result = (new $eventClass())->handle(['model'=>$model]);
                    if($result===false){
                        return false;
                    }
                };
            }
        }

        return true;

    }

    /**
     * 自动拼接数据权限查询条件
     *
     * @param object $query
     * @return void
     */
    public function scopeDataRight($query)
    {
        $model = $this;
        $request = request();
        if(empty($request->check_data_right))return true;

        $resRightSet = $request->rightSet['data']??[];

        $eventList = [];
        if(empty($resRightSet)){
            $eventList = $model->dateRightAction??[]; 
        }else{
            if(empty($resRightSet['model']))return true;
            if($resRightSet['model']=='*'||in_array(Str::snake($model->getName()),(array)$resRightSet['model'])){
                $eventList = $model->dateRightAction??[];
                $eventList = array_merge($eventList,(array)$resRightSet['event_action']??[]);

                $this->autoDataCheck($query,$request);
            }
        }

        if(!empty($eventList)){
            foreach ($eventList as $event) {
                $eventClass = 'app\\task\\data_right\\'.Str::studly($event);
                if(class_exists($eventClass)){
                    $result = (new $eventClass())->handle(['model'=>$this,'query'=>$query]);
                    if($result===false){
                        return false;
                    }
                };
            }
        }

        return true;

    }

    /**
     * 自动处理相关字段
     *
     * @param object $model
     * @return void
     */
    public function autoInsertDeal($model)
    {
        $request = request();

        foreach ($model->rightField as $name => $config) {

            $field = $config['alias']??$config['fieldName'];

            if(!empty($model->$field))continue;
            $typeAttrName = $name.'GetType';
            $type = $request->$typeAttrName??'input';

            if(method_exists($this,$type)){
                $model->$field = $this->$type($request,$model,$config['fieldName']);
            }else{
                $model->$field = 0;
            }
        }

        return true;
        
    }

    /**
     * 自动检测数据权限
     *
     * @param object $model
     * @param object $query
     * @param object $request
     * @return void
     */
    private function autoDataCheck($query,$request)
    {
        $autoCheck = $request->rightSet['auto']??[];

        if(empty($autoCheck))return true;

        foreach ($this->rightField as $name => $config) {

            if(!in_array($name,$autoCheck))continue;

            $field = $config['alias']??$config['fieldName'];

            if(!empty($this->$field))continue;
            $typeAttrName = $name.'GetType';
            $type = $request->$typeAttrName??'login';

            $checkAttrName = 'needCheck'.Str::studly($name);

            if($this->$checkAttrName){
                $query->where([$field=>$this->$type($request,$this,$config['fieldName'])]);
            }
        }
        
    }

    /**
     * 从输入获取
     *
     * @param Request $request 请求对象
     * @param Model $model 数据模型
     * @return void
     */
    private function input($request,$model,$fieldName)
    {
        return $request->param($fieldName,0);
    }

    /**
     * 从登录信息获取
     *
     * @param Request $request 请求对象
     * @param Model $model 数据模型
     * @return void
     */
    private function login($request,$model,$fieldName)
    {
        return $request->loginUser[$fieldName]??0;
    }

    /**
     * 从请求对象获取
     *
     * @param Request $request 请求对象
     * @param Model $model 数据模型
     * @return void
     */
    private function req($request,$model,$fieldName)
    {
        return $request->$fieldName??0;
    }

    /**
     * 清除模型指定属性
     *
     * @param string $name
     * @return Model
     */
    public static function clearAttr($name)
    {
        $model = new static();
        if($model->$name){
            $model->$name = null;
        }

        return $model;
    }
}